#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <time.h>
#include <pthread.h>
#include "font.h"
int a=0;

void showbitmap(bitmap *bm, char *p, int x, int y);
int size(int lcd);

void *content1(void *arg)
{
    font *f = fontLoad("simfang.ttf"); // 指定字库文件，比如simfang.ttf
    
    int lcd=open("/dev/fb0",O_RDWR);

    // 申请一块映射内存
    char *p=calloc(1,size(lcd));
    p = mmap(NULL, size(lcd),PROT_READ|PROT_WRITE,MAP_SHARED, lcd, 0); 
    bzero(p,size(lcd));

    //3.设置字体输出框的大小
    bitmap *bm;       
    bm=createBitmapWithInit(800,60,4,0x000000ff);
    int n=0;
    while(1)
    {
        fontSetSize(f, 50);
        fontPrint(f,bm,800-n%1700,0,"温馨提示：非必要不出门，出门戴口罩！",0x0000ff00,900);     
        showbitmap(bm,p, 0, 420);
        bzero(bm->map,bm->height*bm->width*bm->byteperpixel);        
        n++;
        
        if(n%1700==0)
        {
            a=1;
        }
        usleep(100);
    }
}

void *content2(void *arg)
{
    font *f = fontLoad("simfang.ttf"); // 指定字库文件，比如simfang.ttf
    
    int lcd=open("/dev/fb0",O_RDWR);

    // 申请一块映射内存
    char *p=calloc(1,size(lcd));
    p = mmap(NULL, size(lcd),PROT_READ|PROT_WRITE,MAP_SHARED, lcd, 0); 
    bzero(p,size(lcd));

    //2.设置字体的大小a
    fontSetSize(f, 60);
    //3.设置字体输出框的大小
    bitmap *bm;       
    bm=createBitmapWithInit(800,70,4,0x000000ff);
    int n=0;
    while(1)
    {
        if(n<300)
        {
            fontPrint(f,bm,n%300-240,0,"紧跟党走",0xff000000,800);     
            showbitmap(bm,p, 0, 80);
            bzero(bm->map,bm->height*bm->width*bm->byteperpixel);
        }
        if(n<420)
        {
            fontPrint(f,bm,n%420-240,0,"永不变心",0xff000000,800);     
            showbitmap(bm,p, 0, 150);
            bzero(bm->map,bm->height*bm->width*bm->byteperpixel);
        }
        if(n<540)
        {
            fontPrint(f,bm,n%540-240,0,"勤劳俭朴",0xff000000,800);     
            showbitmap(bm,p, 0, 220);
            bzero(bm->map,bm->height*bm->width*bm->byteperpixel);
        }
        if(n<660)
        {
            fontPrint(f,bm,n%660-240,0,"乐于助人",0xff000000,800);     
            showbitmap(bm,p, 0, 290);
            bzero(bm->map,bm->height*bm->width*bm->byteperpixel);
        }
        n+=10;
        usleep(1);
        if(a==1)  //优化动态效果，使其大致同步
        {
            usleep(100*1000);
            n=0;
            a=0;
        }
    }
}


void *days(void *arg)
{
    font *f = fontLoad("simfang.ttf"); // 指定字库文件，比如simfang.ttf
    
    int lcd=open("/dev/fb0",O_RDWR);

    // 申请一块映射内存
    char *p=calloc(1,size(lcd));
    p = mmap(NULL, size(lcd),PROT_READ|PROT_WRITE,MAP_SHARED, lcd, 0); 
    bzero(p,size(lcd));

    //2.设置字体的大小
    fontSetSize(f, 40);
    //3.设置字体输出框的大小
    bitmap *bm;       
    bm=createBitmapWithInit(800,50,4,0x000000ff);

    struct timeval tv;
    time_t time;
    struct tm *p_time;
    
    char a[7][4]={"天","一","二","三","四","五","六"};
    int year;
    while(1)
    {   
        gettimeofday(&tv,NULL);//获取系统时间，并保存到tv中，注意这里可以精确到微秒
        time=tv.tv_sec+208003785;
        p_time=localtime(&time);//将系统时间转换为本地时间，考虑到本地时区和夏令时标志
        year=p_time->tm_year+1900;
        char buf[100]={0};
        sprintf(buf,"%d年%d月%d日 星期%s %d点%d分%2d秒",year,p_time->tm_mon+1,p_time->tm_mday,a[p_time->tm_wday],p_time->tm_hour,p_time->tm_min,p_time->tm_sec);
       
        //4.把字体输出到输出框中   
        fontPrint(f, bm, 10, 5,buf, 0x00ff0000, 800);

        //5.将bm妥善地放置到LCD上显示出来

        showbitmap(bm,p, 0, 0);

        bzero(bm->map,bm->height*bm->width*bm->byteperpixel);
        usleep(1000);
    }
}

int size(int lcd)
{
    struct fb_var_screeninfo vinfo; // 显卡设备的可变属性结构体
    ioctl(lcd, FBIOGET_VSCREENINFO, &vinfo); // 获取可变属性
    // 获得当前显卡所支持的虚拟区显存大小
    unsigned long width  = vinfo.xres;
    unsigned long height = vinfo.yres;
    unsigned long bpp    = vinfo.bits_per_pixel;
    unsigned long screen_size = width * height * bpp/8;
    return screen_size;
}

void showbitmap(bitmap *bm, char *p, int x, int y)
{    
    for(int j=0;j<bm->height;j++)
    {
        for(int i=0;i<bm->width;i++)
        {
            memcpy(p+(i+x)*4+4*800*(j+y),bm->map+i*4+4*bm->width*j,3);
        }
    }
}

int main(int argc, char const *argv[])
{
    pthread_t t1;
    pthread_create(&t1, NULL, content1, NULL);
    pthread_create(&t1, NULL, content2, NULL);
    pthread_create(&t1, NULL, days, NULL);
    
    pause();
    return 0;
}
